using System;
using MonoLibUsb;
using System.Runtime.InteropServices;
namespace MaplinRobotArm
{
	public class RobotArm : IDisposable
	{
		public bool Ok{get{return device_handle != null;}}
		private MonoUsbSessionHandle sessionHandle = null;
		private	MonoUsbDeviceHandle device_handle = null;
		private IntPtr unmanagedData = IntPtr.Zero;
		
		public RobotArm ()
		{
			try
			{
				int r;
				unmanagedData = Marshal.AllocHGlobal(3);

	            sessionHandle = new MonoUsbSessionHandle();
	            if (sessionHandle.IsInvalid )
				{
					throw new Exception("Failed to get MonoUsbSession");
				}
				
	            device_handle = MonoLibUsb.MonoUsbApi.OpenDeviceWithVidPid(sessionHandle, 0x1267, 0x0000);
	            if (device_handle == null || device_handle.IsInvalid)
				{
					throw new Exception("Failed to find device");
				}
				
	            // Set configuration
	            Console.WriteLine("Set Config..");
				int config = 1;
	            r = MonoLibUsb.MonoUsbApi.GetConfiguration(device_handle, ref config);
	            if (r != 0)
				{
					throw new Exception("Failed to get configuration");
				}
				
	            // Claim interface
	            Console.WriteLine("Set Interface..");
/*	            r = MonoLibUsb.MonoUsbApi.ClaimInterface(device_handle, 0);
	            if (r != 0)
				{
					throw new Exception("Failed to clain interface");
				}*/
			}
			catch
			{//Something went wrong, dispose the stuff that did work.
				Dispose();
			}
		}
		
		public void SendData(byte a,byte b,byte c)
		{
			if( Ok)
			{
				byte []testWriteData = new byte[]{a,b,c};
				Marshal.Copy(testWriteData,0,unmanagedData,3);
	            MonoLibUsb.MonoUsbApi.ControlTransfer(device_handle,0x40,6,0x0100,0,unmanagedData,3,2000);
			}
		}
		
		public void ResetDevice()
		{
			if( Ok )
			{
	            MonoUsbApi.ResetDevice(device_handle);
	            device_handle.Close();
	            device_handle = MonoLibUsb.MonoUsbApi.OpenDeviceWithVidPid(sessionHandle, 0x1267, 0x0000);
			}
		}
	

		#region IDisposable implementation
		public void Dispose ()
		{
			if( unmanagedData != IntPtr.Zero)
			{
				Marshal.FreeHGlobal(unmanagedData);
			}
			
		  // Free and close resources
			if (device_handle != null)
			{
			    if (!device_handle.IsInvalid)
			    {
			        MonoUsbApi.ReleaseInterface(device_handle, 0);
			        device_handle.Close();
			    }
			}
			
			if (sessionHandle!=null)
			{
			    sessionHandle.Close();
			    sessionHandle = null;
			}
		}
		#endregion
}
}

